//错误类型定义

package pkgerrors

import (
	"fmt"
	"nest/internal/utils"
	"os"
	"runtime/debug"
	"strings"
	"time"
)

// Outputter 定义包管理器的输出接口
type Outputter interface {
	// Success 输出成功信息
	Success(message string, args ...interface{})
	// Info 输出普通提示信息
	Info(message string, args ...interface{})
	// Warn 输出警告信息
	Warn(message string, args ...interface{})
	// Error 输出错误信息
	Error(message string, args ...interface{})
	// Fatal 输出致命错误并退出
	Fatal(message string, args ...interface{})
	// Debug 输出调试信息（仅在调试模式下显示）
	Debug(message string, args ...interface{})
}

// 成功输出类型定义
type OutputType int

const (
	OutputTypeSuccess OutputType = iota // 成功
	OutputTypeInfo                      // 信息
	OutputTypeWarn                      // 警告
	OutputTypeError                     // 错误
	OutputTypeFatal                     // 致命错误
	OutputTypeDebug                     // 调试
)

// ErrorLevel 定义错误严重级别
type ErrorLevel int

const (
	LevelFatal       ErrorLevel = iota // 致命错误，需要立即终止
	LevelRecoverable                   // 可恢复错误
	LevelWarning                       // 警告
	LevelInfo                          // 信息
)

// ErrorCode  定义 错误码
const (
	CodeUnknownError      = 10000 // 未知错误
	CodeInvalidArgument   = 10001 // 参数错误
	CodeInvalidFormat     = 10002 // 格式错误
	CodeInvalidState      = 10003 // 状态错误
	CodeInvalidOperation  = 10004 // 操作错误
	CodeInvalidPermission = 10005 // 权限错误
	CodeInvalidNetwork    = 10006 // 网络错误
	CodeInvalidPackage    = 10007 // 包管理错误

)

// ErrorCategory 错误分类
type ErrorCategory int

const (
	CategoryNetwork    ErrorCategory = iota // 网络错误
	CategoryFilesystem                      // 文件系统错误
	CategoryDependency                      // 依赖错误
	CategoryValidation                      // 数据验证错误
	CategoryPermission                      // 权限错误
	CategoryInternal                        // 内部错误
	CategoryPackage                         // 包管理错误
	CategoryUnknown                         // 未知错误
)

// PkgException 包管理器自定义错误
type PkgException struct {
	Code       int                    // 错误码
	Message    string                 // 用户友好消息
	Level      ErrorLevel             // 错误级别
	Category   ErrorCategory          // 错误分类
	Package    string                 // 相关包名
	Version    string                 // 相关版本
	Inner      error                  // 原始错误
	Timestamp  time.Time              // 发生时间
	Stack      []byte                 // 调用栈
	Metadata   map[string]interface{} // 附加元数据
	OutputType OutputType             // 输出类型
}

// 实现error接口
// Error() 方法之所以会“自动执行”，是因为它实现了 error 接口，而 Go 语言在特定场景下会自动调用这个方法
func (e *PkgException) Error() string {
	// 配置日志不显示时间戳和其他前缀
	// log.SetFlags(0)
	var builder strings.Builder
	builder.WriteString(fmt.Sprintf("[错误][%04d]%s ", e.Code, e.Message))

	if e.Package != "" {
		builder.WriteString(fmt.Sprintf(" (package: %s", e.Package))
		if e.Version != "" {
			builder.WriteString(fmt.Sprintf("@%s", e.Version))
		}
		builder.WriteString(")")
	}

	if e.Inner != nil {
		builder.WriteString(fmt.Sprintf("\n原始错误: %v", e.Inner))
	}

	return builder.String()
}

// Unwrap 支持errors.Unwrap
func (e *PkgException) Unwrap() error {
	return e.Inner
}

// WithPackage 设置关联包名
func (e *PkgException) WithPackage(pkg string) *PkgException {
	e.Package = pkg
	return e
}

// WithVersion 设置关联版本
func (e *PkgException) WithVersion(ver string) *PkgException {
	e.Version = ver
	return e
}

// WithMetadata 添加元数据
func (e *PkgException) WithMetadata(key string, value interface{}) *PkgException {
	if e.Metadata == nil {
		e.Metadata = make(map[string]interface{})
	}
	e.Metadata[key] = value
	return e
}

// NewError 创建新错误
func NewError(code int, level ErrorLevel, category ErrorCategory, msg string) *PkgException {
	return &PkgException{
		Code:      code,
		Message:   msg,
		Level:     level,
		Category:  category,
		Timestamp: time.Now(),
		Stack:     debug.Stack(),
		Metadata:  make(map[string]interface{}),
	}
}

// WrapError 包装现有错误
func WrapError(err error, code int, level ErrorLevel, category ErrorCategory, msg string) *PkgException {
	return &PkgException{
		Code:      code,
		Message:   msg,
		Level:     level,
		Category:  category,
		Inner:     err,
		Timestamp: time.Now(),
		Stack:     debug.Stack(),
		Metadata:  make(map[string]interface{}),
	}
}

// Success 输出成功信息
func PrintSuccess(message string, args ...interface{}) {
	var builder strings.Builder
	builder.WriteString(utils.Colorize("✓ SUCCESS ", "32")) // 绿色
	builder.WriteString(utils.Colorize(message, "32"))      // 绿色
	if len(args) > 0 {
		builder.WriteString(utils.Colorize(args[0].(string), "32"))
	}
	builder.WriteString("\n")

	fmt.Fprint(os.Stderr, builder.String())
}

// Info 输出普通提示信息
func PrintInfo(message string, args ...interface{}) {
	var builder strings.Builder
	builder.WriteString(utils.Colorize(message, "36")) // 青色
	if len(args) > 0 {
		builder.WriteString(utils.Colorize(args[0].(string), "36"))
	}
	builder.WriteString("\n")
	fmt.Fprint(os.Stderr, builder.String())
}

// err 输出错误提示信息
func PrintError(message string, args ...interface{}) {
	var builder strings.Builder
	builder.WriteString(utils.Colorize(message, "31")) // 红色
	if len(args) > 0 {
		builder.WriteString(utils.Colorize(args[0].(string), "31"))
	}
	builder.WriteString("\n")

	fmt.Fprint(os.Stderr, builder.String())
}

// Success 输出成功信息
func Success(message string, args ...interface{}) *PkgException {
	return &PkgException{
		OutputType: OutputTypeInfo,
		Level:      LevelInfo,
		Message:    message,
	}
}

// Info 输出普通提示信息
func Info(message string, args ...interface{}) *PkgException {
	return &PkgException{
		OutputType: OutputTypeInfo,
		Level:      LevelInfo,
		Message:    message,
	}
}

// Warn 输出警告信息
func Warn(message string, args ...interface{}) *PkgException {
	return &PkgException{
		OutputType: OutputTypeWarn,
		Level:      LevelWarning,
		Message:    message,
		Code:       0,
	}
}

// Error 输出错误信息
func Error(message string, args ...interface{}) *PkgException {
	return &PkgException{
		OutputType: OutputTypeError,
		Level:      LevelInfo,
		Message:    message,
		Code:       0,
	}
}

// Fatal 输出致命错误并退出
func Fatal(message string, args ...interface{}) *PkgException {
	return &PkgException{
		OutputType: OutputTypeFatal,
		Level:      LevelFatal,
		Message:    message,
		Code:       0,
	}
}

// Debug 输出调试信息（仅在调试模式下显示）
func Debug(message string, args ...interface{}) *PkgException {
	/* if o.debugMode {
		formatted := o.formatWithColor(colorMagenta, "DEBUG: "+message, args...)
		fmt.Fprintln(o.Stderr, formatted)
	} */

	return &PkgException{
		OutputType: OutputTypeDebug,
		Level:      LevelInfo,
		Message:    message,
		Code:       0,
	}
}
